﻿#include "demux.h"
#include <QDebug>
#include "ffmpegutils.h"
extern "C"
{
#include "libavformat/avformat.h"
}

Demux::Demux()
{

}

Demux::~Demux()
{
    if(avformat_ctx)
    {
        qDebug() << "-------avformat_free_context(avformat_ctx)-------";
        avformat_close_input(&avformat_ctx);
        avformat_free_context(avformat_ctx);
    }    
}

bool Demux::open_stream(const char* url)
{
    this->url = url;
    AVDictionary *options = 0;
    //设置rtsp流tcp协议已打开
    av_dict_set(&options,"rtsp_transport","tcp",0);
    //网络延时时间
    av_dict_set(&options,"max_delayt","500",0);

    //打开 avformatcontext 上下文,0表示打开成功
    int ret = avformat_open_input(&avformat_ctx,url,0,&options);
    if(ret != 0)
    {
        qDebug() << "open avformat_ctx error";
        return false;
    }
    qDebug() << "open avformat_ctx success";
    if(!getStreamInfo())
    {
        return false;
    }
    return true;
}

AVCodecParameters *Demux::copyAVCodecParameters(int index)
{
    if (avformat_ctx == NULL)
    {
        return NULL;
    }
    //重新创建一份 AVCodecParameters 对象空间
    AVCodecParameters* codec_params = NULL;
    codec_params = avcodec_parameters_alloc();
    int ret = avcodec_parameters_copy(codec_params, avformat_ctx->streams[index]->codecpar);
    if(ret < 0)
    {
        qDebug() << "avcodec_parameters_copy(codec_params, avformat_ctx->streams[index]->codecpar); ---- error";
        avcodec_parameters_free(&codec_params);
        return NULL;
    }
    return codec_params;
}

bool Demux::getStreamInfo()
{
    //打开成功,获取流信息
    int ret = avformat_find_stream_info(avformat_ctx, 0);
    if(ret < 0)
    {
        qDebug() << "avformat_find_stream_info error";
        return false;
    }
    //void av_dump_format(AVFormatContext *ic, int index, const char *url, int is_output);
    //打印流的信息
    av_dump_format(avformat_ctx,0,url,0);
    //获取视频频索引
    video_stream_index = av_find_best_stream(avformat_ctx,AVMEDIA_TYPE_VIDEO,-1,-1,NULL,0);
    //获取音频索引
    audio_stream_index = av_find_best_stream(avformat_ctx,AVMEDIA_TYPE_AUDIO,-1,-1,NULL,0);
    return true;
}

int Demux::getVideoStreamIndex()
{
    return this->video_stream_index;
}

int Demux::getAudioStreamIndex()
{
    return this->audio_stream_index;
}

AVPacket *Demux::read()
{
    if (!avformat_ctx)
    {
        return 0;
    }
    //要加入到缓冲队列中所以要每次开辟空间
    AVPacket *pkt = av_packet_alloc();
    //读取一帧h.264
    int ret = av_read_frame(avformat_ctx, pkt);
    if (ret != 0)
    {
        av_packet_free(&pkt);
        return 0;
    }
    //pts转换为毫秒
    double ms = FFmpegUtils::rationalToDouble(avformat_ctx->streams[pkt->stream_index]->time_base.num,avformat_ctx->streams[pkt->stream_index]->time_base.den);
    pkt->pts = pkt->pts*(1000 * ms);
    pkt->dts = pkt->dts*(1000 * ms);
    return pkt;
}
